package com.airlines.crewassignment.domain.util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.airlines.common.DateTimeRangeUtil;
import com.airlines.common.ListSortUtil;
import com.airlines.crewassignment.domain.Crew;
import com.airlines.crewassignment.domain.CrewPositionAssignment;
import com.airlines.crewassignment.domain.DateTimeRange;
import com.airlines.crewassignment.domain.FlightInfo;
import com.airlines.crewassignment.domain.LinkLine;
import com.airlines.crewassignment.domain.Position;

/**
 * @author xxxx
 * @date 2018年4月17日 
 * @description
 */
public class LinkLineLoopUtil {
	static Log log = LogFactory.getLog(LinkLineLoopUtil.class);
	/**
	 * 检查判断 该飞行员历史的最后一次机场，与已经安排的任务的机场，是否是首位相连的
	 * @param list
	 * @param crew
	 * @return
	 */
	public static boolean crewAirportOneLine(List<CrewPositionAssignment> list,Crew crew){
		
		if(CollectionUtils.isEmpty(list)){
			return true;
		}
		
		Set<FlightInfo> flightInfoSet = CrewPositionAssignmentUtil.getFlightInfoSet(list);
		if(CollectionUtils.isEmpty(flightInfoSet)){
			return true;
		}
		
		List<FlightInfo> flightInfoList = new ArrayList<>();
		flightInfoList.addAll(flightInfoSet);
		ListSortUtil.sort(flightInfoList, true, "sta");
		
		String lastArrivalAirport= crew.getCrewFlightExperience().getLastAirport();
		if(StringUtils.isNotBlank(lastArrivalAirport)){
			String departureAirport0 = flightInfoList.get(0).getDepartureAirport(); 
			if(!arrivalToDepartureCheck(lastArrivalAirport, departureAirport0)){
				return false;
			}
		}
		
		for(int i = 0 ; i < flightInfoList.size()-1 ; i++){
			String arrivalAirport = flightInfoList.get(i).getArrivalAirport();
			String departureAirport = flightInfoList.get(i+1).getDepartureAirport();
			if(!arrivalToDepartureCheck(arrivalAirport, departureAirport)){
				return false;
			}
			
		}
		return true;
	}
	
	/**
	 * 判断首位机场是否相连
	 * @param arrivalAirport
	 * @param departureAirport
	 * @return
	 */
	private static boolean arrivalToDepartureCheck(String arrivalAirport,String departureAirport){
		return StringUtils.equals(arrivalAirport, departureAirport);
	}
	
	/**
	 * 同一个任务环中的任务，机组人员相同
	 * 反过来说，就是任意一个任务的前置任务的机组人员与本机组相同
	 * @param list
	 * @return
	 */
	
	public static boolean oneLoopIdFactOneCrewGroup1(List<CrewPositionAssignment> list,String loopIdFact){
		boolean flag = true;
		
		
		//在调用本方法前，list 就是已经是同一个任务环的所有list的了
		Set<LinkLine> linkLineSet = CrewPositionAssignmentUtil.getLinkLineSet(list);
		for(LinkLine l : linkLineSet){
			Set<String> thisWrokcodeSet = getWorkcodeSet(list,l);	
			
			//如果本连线人员为空，则直接进入下一循环
			if(CollectionUtils.isEmpty(thisWrokcodeSet)){
				continue;
			}
			
			if(l.getLastLinkLineBaseInfo() !=null){
				Set<String> lastWrokcodeSet = getWorkcodeSet(list, l.getLastLinkLineBaseInfo());
				if(!CollectionUtils.isEqualCollection(thisWrokcodeSet,lastWrokcodeSet)){
					flag = false;
					break;
				}
			}
		}
		
		return flag;
	}
	
	
	public static boolean oneLoopIdFactOneCrewGroup(List<CrewPositionAssignment> list,String loopIdFact){
		
		if(StringUtils.equals(loopIdFact, "13-20180408") && list.size() == 6){
			log.debug("13-20180408");
		}
		
		//1.查询所有连线的所有机组人员
		Set<String> allWorkcodeSet = new HashSet<>();
		for(CrewPositionAssignment c : list){
			String workcode = c.getCrew().getWorkcode();
			allWorkcodeSet.add(workcode);
		}
		
		//2.查询每个相同连线的机组人员，并与allWorkcode 比对
		for(CrewPositionAssignment c : list){
			String crewLinkLineKey =  c.getPosition().getCrewLinkLineKey();
			Set<String> crewLinkLineWorkcodeSet = new HashSet<>();
			for(CrewPositionAssignment cTemp : list){
				String crewLinkLineKeyTemp =  cTemp.getPosition().getCrewLinkLineKey();
				if(StringUtils.equals(crewLinkLineKey, crewLinkLineKeyTemp)){
					String workcodeTemp = cTemp.getCrew().getWorkcode();
					crewLinkLineWorkcodeSet.add(workcodeTemp);
				}
			}
			
			if(!CollectionUtils.isEqualCollection(allWorkcodeSet, crewLinkLineWorkcodeSet)){
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * 从解决方案中，查询该连线的所有的飞行员列表
	 * 
	 * 注意：如果在本连线中已经存在人员（已经提前安排好的，或者是在排班日期前的人员），则这些人员也算作该连线 的飞行员列表
	 * @param list
	 * @param l
	 * @return
	 */
	private static  Set<String> getWorkcodeSet(List<CrewPositionAssignment> list,LinkLine l){
		Set<String> workcodeSet = new HashSet<>();
		//1.从所有解决方案中查找人员变量
		for(CrewPositionAssignment cpa : list){
			String crewLinkLineKeyTemp  = cpa.getPosition().getLinkLine().getCrewLinkLineKey();
			if(StringUtils.equals(l.getCrewLinkLineKey(), crewLinkLineKeyTemp)){
				String workcode = cpa.getCrew().getWorkcode();
				if(StringUtils.isNotBlank(workcode)){
					workcodeSet.add(workcode);
				}
				
			}
		}
		
		//2.从本连线查找已经安排的人员
		List<Position> positionList = l.getPositionList();
		for(Position p : positionList){
			String workcode = 	p.getWorkcode();
			if(StringUtils.isNotBlank(workcode)){
				workcodeSet.add(workcode);
			}
		
		}
		
		return workcodeSet;
	}
	
	
	
	@Deprecated
	public static boolean sameCrewAsLastLinkLine(List<CrewPositionAssignment> list,Position position){

		LinkLine thisLinkLine = position.getLinkLine();
		LinkLine lastLinkLine = thisLinkLine.getLastLinkLineBaseInfo();
		if(lastLinkLine == null){
			return true;
		}
		
		Set<String> thisWrokcodeSet = getWorkcodeSet(list,thisLinkLine);
		Set<String> lastWrokcodeSet = getWorkcodeSet(list,lastLinkLine);
		/*if(CollectionUtils.isEmpty(thisWrokcodeSet) || CollectionUtils.isEmpty(lastWrokcodeSet)){
			flag = true;
		}else*/
		if(CollectionUtils.isEqualCollection(thisWrokcodeSet, lastWrokcodeSet)){
			return  true;
		}else{
			return false;
		}
	
	}
	
	public static void main(String[] args) {
		Set<String> lastWrokcodeSet = new HashSet<>();
		lastWrokcodeSet.add("b");
		lastWrokcodeSet.add("a");
		log.debug("isEmpty"+CollectionUtils.isEmpty(lastWrokcodeSet));
		
		
		Set<String> thisWrokcodeSet = new HashSet<>();
		thisWrokcodeSet.add("a");
		thisWrokcodeSet.add("b");
		log.debug("比较结果"+CollectionUtils.isEqualCollection(thisWrokcodeSet,lastWrokcodeSet));
		
	}
	
	/*
	public static boolean positionListHasCrew(LinkLine linkLine ,List<Position> LastpositionList,Crew crew){
		Date beforeFlightDate = crew.getCrewFlightExperience().getBeforeFlightDate();
		boolean flag = false;
		for(Position p: LastpositionList){
			if(p.getFlightDate().before(beforeFlightDate)){
				if(StringUtils.equals(p.getWorkcode(), crew.getWorkcode())){
					flag = true;
				}
			}
		}
		return flag;
	}
	*/
	
	
	public static boolean positionListHasCrew( Set<String> lastWorkcodeSet,Crew crew){
		if(CollectionUtils.isEmpty(lastWorkcodeSet)){
			return true;
		}
			
		for(String lastWorkcode : lastWorkcodeSet){
			if(StringUtils.equals(lastWorkcode, crew.getWorkcode())){
				return true;
			}
				
		}
		return false;
	}
	/**
	 * 判断两个号位时间上是否有冲突（连线时间）
	 * @param p1
	 * @param p2
	 * @return
	 */
	public static boolean positionIsIntersection(Position p1,Position p2){
		LinkLine l1 = p1.getLinkLine();
		DateTimeRange dtr1 = new DateTimeRange(l1.getTd(),l1.getTa());
		
		LinkLine l2 = p2.getLinkLine();
		DateTimeRange dtr2 = new DateTimeRange(l2.getTd(),l2.getTa());
		
		return DateTimeRangeUtil.isIntersection(dtr1, dtr2);
		
	}
}
